import { isNumber, isObject, isString, ShapeFlags } from "../shared/index.js";

export function isVNode(val) {
  return !!(val && val.__v_isVNode);
}

export function convert(child) {
  if (isString(child) || isNumber(child)) {
    return createVNode(Text, null, child);
  } else {
    return child;
  }
}

export function normalizeChildren(children) {
  return children.map(convert);
}

export const Text = Symbol("Text");

export const Fragment = Symbol("Fragment");

export function isSameVnode(n1, n2) {
  return n1.type === n2.type && n1.key === n2.key;
}

export function createVNode(type, props = {}, children = null, patchFlag) {
  const shapeFlag = isString(type)
    ? ShapeFlags.ELEMENT // 元素
    : isObject(type)
    ? ShapeFlags.STATEFUL_COMPONENT // 组件
    : 0;
  const vnode = {
    shapeFlag,
    __v_isVNode: true,
    type,
    props,
    key: props && props.key,
    el: null, // 每个虚拟节点都对应一个真实节点，用来存放真实节点，后续更新的时候会产生新的虚拟节点，比较差异，更新真实dom
    children,
    patchFlag,
    dynamicChildren: null,
  };
  if (currentBlock && vnode.patchFlag > 0) {
    currentBlock.push(vnode);
  }
  if (children) {
    let type = 0;
    if (Array.isArray(children)) {
      vnode.children = normalizeChildren(children);
      type = ShapeFlags.ARRAY_CHILDREN;
    } else if (isObject(children)) {
      type = ShapeFlags.SLOTS_CHILDREN;
    } else {
      vnode.children = String(children);
      type = ShapeFlags.TEXT_CHILDREN;
    }
    vnode.shapeFlag |= type;
  }

  return vnode;
}

let currentBlock = null;
export function openBlock() {
  currentBlock = [];
}

export function closeBlock() {
  currentBlock = null;
}

export function createElementBlock(type, props, children, patchFlag = 0) {
  const vnode = createVNode(type, props, children, patchFlag);
  vnode.dynamicChildren = currentBlock; // 给虚拟节点添加动态孩子
  closeBlock(); // 复制后结束收集操作
  return vnode;
}

export { createVNode as createElementVNode };

export function toDisplayString(val) {
  return isString(val)
    ? val
    : isObject(val)
    ? JSON.stringify(val)
    : String(val);
}
